<?php

use app\admin\model\Member;
use app\admin\model\SysConfig;
use app\common\CacheKey;
use app\common\Status;
use think\facade\Lang;
use think\facade\Log;
use think\facade\Config;
use think\Db;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

// 应用公共文件

/**
 * 发送http请求
 * @param $url
 * @param bool $post
 * @param array $param
 * @param bool $https
 * @param null $header
 * @return mixed
 */
function curlRequest($url, $post = false, $param = array(), $https = false, $header = null)
{
    //curl_init 初始化的时候传递url
    $ch = curl_init($url);
    //curl_setopt 设置一些请求选项
    if ($post) {
        //设置请求方式和请求参数
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
    }
    // https请求，默认会进行验证
    if ($https) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    }
    //设置header头
    if (!empty($header)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT_MS, 20000);
    //curl_exec 执行请求会话（发送请求）
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $res = curl_exec($ch);
    //curl_close 关闭请求会话
    curl_close($ch);
    return $res;
}

/**
 * 公用接口返回数据结构
 * @param $code
 * @param string $msg
 * @param string $data
 * @return \think\response\Json
 */
function returnJson($code, $msg = '', $data = '')
{
    $array = array();
    $array['code'] = $code;
    $array['data'] = camelCase($data);
    $array['msg'] = $msg;
    return json($array);
}

/**
 * 将数组中key下划线转换成小驼峰
 * @param $arr
 * @return array
 */
function camelCase($arr)
{
    if (!is_array($arr)) {   //如果非数组原样返回
        return $arr;
    }
    $temp = [];
    foreach ($arr as $key => $value) {
        $key1 = convertUnderline($key, FALSE);
        $value1 = camelCase($value);
        $temp[$key1] = $value1;
    }
    return $temp;
}

/**
 * 将下划线命名转换为驼峰式命名
 * @param $str
 * @param bool $uc_first
 * @return string|string[]
 */
function convertUnderline($str, $uc_first = true)
{
    $str = ucwords(str_replace('_', ' ', $str));
    $str = str_replace(' ', '', lcfirst($str));
    return $uc_first ? ucfirst($str) : $str;
}

/**
 * @param $action
 * @param $error
 */
function errorLog($action, $error)
{
    Log::init(['type' => 'File', 'path' => '../runtime/errorlogs/']);
    Log::write($action . "\n" . '============error=============start' . "\n" . $error . "\n" . '============error=============end');
}

//短信验证码云片
function sendMsg($phone, $code, $type = '1')
{
    $data = array(
        'apikey' => '8661a79636fb05390c4342b036402c8d',
        'text' => '【六安名流】你的验证码: ' . $code . ' 请勿向其他人泄露,30分钟内有效!',
        'mobile' => $phone,
    );
    $ch = curl_init();
    /* 设置验证方式 */
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept:text/plain;charset=utf-8',
        'Content-Type:application/x-www-form-urlencoded', 'charset=utf-8'));
    /* 设置返回结果为流 */
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    /* 设置超时时间*/
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    /* 设置通信方式 */
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_URL, 'https://sms.yunpian.com/v2/sms/single_send.json');
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
    $result = curl_exec($ch);
    $error = curl_error($ch);
    return json_decode($result, true);
}

/**
 * 密码加密
 * @param $pwd
 * @return false|string|null
 */
function encryptPwd($pwd)
{
    return password_hash($pwd, PASSWORD_DEFAULT);
}

/**
 * 短信验证码校验
 * @param $code
 * @param $str
 * @return string|\think\response\Json
 */
function checkCode($code, $str)
{
    $key = sprintf(CacheKey::USER_CAPTCHA, $str);
    $real_code = redis()->get($key);
    // 如果验证码不存在，则已过期
    if (!$real_code) {
        return returnJson(Status::CODE_ERROR, Lang::get('msg_code_past'));
    }
    // 用户传的验证码和真实验证码不一致则验证码错误
    if ($code != $real_code) {
        return returnJson(Status::CODE_ERROR, Lang::get('msg_code_error'));
    }
    // 删除已使用的验证码
    redis()->del($key);
    return '';
}


/**
 * 获取用户真实IP地址
 * @param int $type
 * @param bool $adv
 * @return mixed
 */
function get_client_ip($type = 0, $adv = true)
{
    $type = $type ? 1 : 0;
    static $ip = null;
    if (null !== $ip) {
        return $ip[$type];
    }

    $httpAgentIp = Config::get('http_agent_ip');

    if ($httpAgentIp && isset($_SERVER[$httpAgentIp])) {
        $ip = $_SERVER[$httpAgentIp];
    } elseif ($adv) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown', $arr);
            if (false !== $pos) {
                unset($arr[$pos]);
            }
            $ip = trim(current($arr));
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip = $long ? [$ip, $long] : ['0.0.0.0', 0];
    return $ip[$type];
}

/**
 * 生成唯一6位数邀请码
 * @param int $length
 * @return string
 */
function create_invite_code($length = 5)
{
    $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $rand = $code[rand(0, 25)]
        . strtoupper(dechex(date('m')))
        . date('d')
        . substr(time(), -5)
        . substr(microtime(), 2, 5)
        . sprintf('%02d', rand(0, 99));
    for (
        $a = md5($rand),
        $s = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
        $d = '',
        $f = 0;
        $f < $length;
        $g = ord($a[$f]),
        $d .= $s[($g ^ ord($a[$f + 8])) - $g & 0x1F],
        $f++
    ) ;
    return $d;
}

/**
 * @Title: getRandChar
 * @Description: 生成随机字符串函数
 * @param $length
 * @return null|string
 */
function getRandChar($length)
{
    $str = null;
    $strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    $max = strlen($strPol) - 1;

    for ($i = 0; $i < $length; $i++) {
        $str .= $strPol[rand(0, $max)];
    }
    return $str;
}

if (!function_exists('redis')) {
    // 获取容器对象实例
    function redis($db_select = 1)
    {
        return \app\service\Redis::redis($db_select);
    }
}

/**
 * 公私钥转换
 * @param $key
 * @param int $type
 * @return string
 */
function transSecretKey($key, $type = 1)
{
    $trans_key = chunk_split($key, 64, "\n");
    if ($type == 1) {
        $trans_key = "-----BEGIN RSA PRIVATE KEY-----\n$trans_key-----END RSA PRIVATE KEY-----\n";
    } else {
        $trans_key = "-----BEGIN PUBLIC KEY-----\n$trans_key-----END PUBLIC KEY-----\n";
    }
    return $trans_key;
}

/**
 * RSA私钥加密 - 使用自己的私钥加密
 * @param $data
 * @param $private_key
 * @return string
 */
function encryption($data, $private_key)
{
    $signString = getSignString($data);
    $privateKeyId = openssl_pkey_get_private($private_key);
    $signature = '';
    openssl_sign($signString, $signature, $privateKeyId, OPENSSL_ALGO_MD5);
    openssl_free_key($privateKeyId);
    return base64_encode($signature);
}

/**
 * 拉取文件
 * @param $url
 * @param $data
 * @return bool|string
 */
function getFileCurl($url, $data)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_SSLVERSION, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    $res = curl_exec($ch);
    curl_close($ch);
    return $res;
}

/**
 * 序列化待签名数据为字符串
 * @param $data
 * @return string
 */
function getSignString($data)
{
    unset($data['sign']);
    ksort($data);
    reset($data);
    $pairs = array();
    foreach ($data as $k => $v) {
        $pairs[] = "$k=$v";
    }
    return implode('&', $pairs);
}

/**
 * 获取风控平台提现手续费
 * @return false|mixed
 */
function getWithdrawMoney()
{
    $private_key = transSecretKey(env('External.PRIVATE_KEY'));
    $time = time();
    $data = array('timestamp' => $time);
    $sign = encryption($data, $private_key);
    $data['sign'] = $sign;
    $find_url = env('External.APIDOMAIN') . 'getTransactionFee';
    $res = json_decode(curlRequest($find_url, true, $data), true);
    if ($res && $res['code'] == 200 && isset($res['data']['btc'])) {
        return $res['data']['btc'];
    } else {
        return false;
    }
}

/**
 * 生成唯一订单号
 * @param int $num
 * @return string
 */
function createOrderNumber($num = 8)
{
    //返回字符串长度为30的字符串
    return date('YmdHis') . substr(microtime(), 2, 8) . mt_rand(10000000, 99999999);
}

/**
 * 保留小数
 * @param $num
 * @param int $float
 * @return string
 */
function keep($num, $float = 2)
{
    $num = bcmul($num, 1, $float);
    $arr = explode('.', $num);
    // 个位数取整
    if ((isset($arr[1]) && strlen($arr[0]) == 1 && $arr[1] == "00") || $num == 0) {
        $num = $arr[0];
    } elseif (explode(',', $num) === false) {
        $num .= '.00';
    }
    return $num;
}

/**
 * 去除多余的0
 * @param $s
 * @return string|string[]|null
 */
function del0($s)
{
    $s = trim(strval($s));
    if (preg_match('#^-?\d+?\.0+$#', $s)) {
        return preg_replace('#^(-?\d+?)\.0+$#', '$1', $s);
    }
    if (preg_match('#^-?\d+?\.[0-9]+?0+$#', $s)) {
        return preg_replace('#^(-?\d+\.[0-9]+?)0+$#', '$1', $s);
    }
    return $s;
}

/**
 * 获取当天时间戳
 * @param int $type
 * @return array
 */
function getNowTime($type = 1)
{
    $start_time = date('Y-m-d 00:00:00');
    $end_time = date('Y-m-d 23:59:59');
    if ($type == 2) {
        $start_time = strtotime($start_time);
        $end_time = strtotime($end_time);
    }
    return [$start_time, $end_time];
}

/**
 * 返回分页条数
 * @param $size
 * @return int|mixed
 */
function get_page_size($size)
{
    if (!$size || $size > 15) {
        $size = 15;
    }
    return $size;
}

/**
 * @Title: httpUrl
 * @Description: http请求
 * @param $url
 * @param bool $params 请求数据
 * @param int $ispost 0/1，是否post
 * @param array $header $header
 * @param bool $verify 是否验证ssl
 * @return bool|mixed 出错时返回false
 * @Author: 李军伟
 */
function httpUrl($url, $params = false, $header = array(), $ispost = 0, $verify = false)
{
    $httpInfo = array();
    $ch = curl_init();
    if (!empty($header)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    }

    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60);
    curl_setopt($ch, CURLOPT_TIMEOUT, 60);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    //忽略ssl证书
    if ($verify === true) {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    } else {
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    }
    if ($ispost) {
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        curl_setopt($ch, CURLOPT_URL, $url);
    } else {
        if (is_array($params)) {
            $params = http_build_query($params);
//             halt($params);
        }
        if ($params) {
//            file_put_contents('url.txt', $url . '?' . $params);
            curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
        } else {
            curl_setopt($ch, CURLOPT_URL, $url);
        }
    }
    $response = curl_exec($ch);
    if ($response === FALSE) {
        trace("cURL Error: " . curl_errno($ch) . ',' . curl_error($ch), 'error');
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $httpInfo = array_merge($httpInfo, curl_getinfo($ch));
        trace($httpInfo, 'error');
        return false;
    }
    curl_close($ch);
    return $response;
}

/**
 * 发送curl请求
 * @param $url 'https://www.wenlin.com/'
 * @param bool $is_post true
 * @param array $data ['email' => 'xxx@xxx.com', 'password' => 'xxx']
 * @param array $header ['Content-Type:application/x-www-form-urlencoded', 'X-Requested-With:XMLHttpRequest']
 * @param bool $ssl false
 * @param bool $is_json false
 * @param int $time_out 0
 * @return array
 */
function http_curl($url, $is_post = true, $data = [], $header = [], $ssl = false, $is_json = false, $time_out = 0)
{
    $curl = curl_init();
    // 设置url
    curl_setopt($curl, CURLOPT_URL, $url);

    //json处理
    if ($is_json && $data) {
        $data = json_encode($data);
        $header = array_merge($header, ['Content-Type: application/json']);
    }

    // 将头文件的信息作为数据流输出
    curl_setopt($curl, CURLOPT_HEADER, false);
    // 请求结果以字符串返回,不直接输出
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    // 禁止 cURL 验证对等证书
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    // 设置头信息
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    //identity", "deflate", "gzip“，三种编码方式，如果设置为空字符串，则表示支持三种编码方式。当出现乱码时，可设置此字符串
    curl_setopt($curl, CURLOPT_ENCODING, '');
    //设置http版本。HTTP1.1是主流的http版本
    curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
    //如果curl版本，大于7.28.1，得是2才行,7.0版本的php自带的curl版本为7.40.1.使用php7以上的，就能确保没问题
    $ssl = $ssl ? 2 : 0;
    // 检查服务器SSL证书中是否存在一个公用名
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, $ssl);
    //连接对方主机时的最长等待时间。设置为10秒时，如果对方服务器10秒内没有响应，则主动断开链接。为0则，不限制服务器响应时间
    curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $time_out);
    //CURLOPT_TIMEOUT：整个cURL函数执行过程的最长等待时间，也就是说，这个时间是包含连接等待时间的
    curl_setopt($curl, CURLOPT_TIMEOUT, 0);
    if ($is_post) {
        // 设置POST请求
        curl_setopt($curl, CURLOPT_POST, true);
        // 构建参数
        if ($is_json) {
            //如果是json字符串的方式，不能用http_build_query函数
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        } else {
            //如果是数组的方式,要加http_build_query，不加的话，遇到二维数组会报错。
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
        }
    } else {
        // GET
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
    }

    // 执行请求
    $response = curl_exec($curl);
//    $content_type = curl_getinfo($curl, CURLINFO_CONTENT_TYPE);//返回的CONTENT_TYPE类型
//    $http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE);//返回的http状态码


    $result = [
        'HTTP_MSG' => 'SUCCESS',
        'HTTP_BODY' => json_decode($response, true),
        'HTTP_ERROR' => curl_error($curl),//错误信息，如果没有错误就是空字符串
//            'HTTP_HEADER' => $content_type,
//            'HTTP_CODE' => $http_code,
    ];
    curl_close($curl);
    return $result;
}

/**
 * 旷视验证
 * @param $url
 * @param $data
 * @return mixed|string
 */
function ks_post($url, $data)
{
    $curl = curl_init();
    curl_setopt_array($curl, array(
        CURLOPT_URL => $url,
        CURLOPT_HTTPHEADER => array('Content-Type: multipart/form-data'),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "POST",
        CURLOPT_POSTFIELDS => $data,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_HTTPHEADER => array("cache-control: no-cache"),
    ));
    $response = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);
    if ($err) {
        return "cURL Error #:" . $err;
    } else {
        return json_decode($response, true);
    }
}

/**
 * csv_get_lines 读取CSV文件中的某几行数据
 * @param $csv_file // csv文件路径
 * @param $lines // 读取行数
 * @param $offset // 起始行数
 * @param array $head_arr
 * @return array|bool
 */
function csv_get_lines($csv_file, $lines, $offset = 0, $head_arr = [])
{
    if (!file_exists($csv_file)) {
        return false;
    }
    if (!$fp = fopen($csv_file, 'r')) {
        return false;
    }
    $i = $j = 0;
    while (false !== ($line = fgets($fp))) {
        if ($i++ < $offset) {
            continue;
        }
        break;
    }
    $data = array();
    while (($j++ < $lines) && !feof($fp)) {
        if ($row_Data = fgetcsv($fp)) {
            $data[] = array_combine($head_arr, $row_Data);
        }
    }
    fclose($fp);
    return $data;
}

/**
 * 图片上传
 * @param string $folder
 * @return bool|int|string
 */
function uploadFile($folder = 'img')
{
    $file = request()->file('file');
    if (!$file || $file->getError()) {
        return false;
    }
    $info = $file->getInfo();                            // 得到文件的名称
    $temp = explode('.', $info['name']);        // 用.分割数组
    $img_type = end($temp);                       // 取数组的最后一个
    $file_size = $info['size'];
    $file_type = ['jpg', 'jpeg', 'gif', 'png', 'word', 'pdf', 'mp4', 'mkv', 'ts', 'rmvb', 'avi', 'wmv'];//定义图片类型
    if (!in_array(strtolower($img_type), $file_type)) {
        return 1;
    }
    // 验证文件大小(最大50M 52428800字节)
    if ($file_size > 52428800) {
        return 2;
    }
    // 移动路径
    $upload_path = "upload/{$folder}/";
    // 缩略保存路径
    $save_path = "upload/{$folder}/";
    // 移动至 $upload_path
    $info = $file->move($upload_path);

    // 压缩图片（大于3M）
    if ($file_size > 3145728) {
        // 打开移动的图片
        $image = \think\Image::open($save_path . $info->getSaveName());
        $image->thumb(1000, 1000)->save($save_path . $info->getSaveName());
    }
    if ($info) {
        $path = str_replace('\\', '/', $info->getSaveName());
        return "/upload/{$folder}/" . $path;
    } else {
        // 上传失败获取错误信息
        return 3;
    }
}

// 通用日志记录
function comLog($log_name, $log_content)
{
    Log::init(['type' => 'File', 'path' => ROOT_PATH . "runtime/{$log_name}" . DS]);
    Log::write($log_content);
}

/**
 * 生成随机数
 * @param $len
 * @return string
 */
function randomNumber($len)
{
    $start_num = 0;
    $end_num = 9;
    for ($i = 1; $i < $len; $i++) {
        $start_num .= 0;
        $end_num .= 9;
    }
    return str_pad(mt_rand($start_num, $end_num), $len, "0", STR_PAD_BOTH);
}

/**
 * 类型转换
 * @param $type
 * @return string
 */
function getMold($type)
{
    if ($type == 1) {
        $mold = 'auth';
    } else {
        $mold = 'pass';
    }
    return $mold;
}

/**
 * 发送邮件
 * @param $to
 * @param $subject
 * @param $content
 * @return bool
 */
function sendMail($to, $subject, $content)
{
    $param = [
        'appid' => config('email_app_id'),
        'signature' => config('email_signature'),
        'from' => config('email_from'),
        'to' => $to,
        'subject' => $subject,
        'html' => $content,
    ];

    $res = curlRequest('https://api.mysubmail.com/mail/send.json', true, $param);
    $res = json_decode($res, true);

    if (isset($res['status']) && $res['status'] == 'success') {
        return true;
    }
    return false;
}

/**
 * 时间戳转换
 * @param $time
 * @return false|string
 */
function getDateTime($time)
{
    $date = "";
    if (!empty($time)) {
        $date = date("Y-m-d H:i:s", $time);
    }
    return $date;
}

/**
 * 生成csv文件
 * @param string $csv_body csv内容数组（一般是二维数组）
 * @param array $csv_header 列字段名
 * @param string $path 保存的路径
 * @return mixed
 */
function create_csv_file($csv_body, array $csv_header, $path)
{
    // 头部标题
    if (!$csv_header) {
        return false;
    }
    /**
     * 开始生成
     * 1. 首先将数组拆分成以逗号（注意需要英文）分割的字符串
     * 2. 然后加上每行的换行符号，这里建议直接使用PHP的预定义
     * 常量PHP_EOL
     * 3. 最后写入文件1
     */
    // 打开文件资源，不存在则创建1
    $des_file = $path;
    $fp = fopen($des_file, 'a');// 处理头部标题
    $header = implode(',', $csv_header) . PHP_EOL;// 处理内容
    $content = '';
    foreach ($csv_body as $k => $v) {
        $content .= implode(',', $v) . PHP_EOL;
    }// 拼接

    $csv = $header . $content;// 写入并关闭资源
    fwrite($fp, $csv);
    fclose($fp);
    return true;
}

/**
 * 得需要按月分表的,表Db对象
 * @param string $table_name 表名
 * @param mixed $date 年月
 * @return object
 */
function getTableObject($table_name, $date = '')
{
    $date = $date ? $date : date('Ym');
    return Db::name($table_name . '_' . $date);
}

function hidtel($phone)
{
    $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i', $phone); //固定电话
    if ($IsWhat == 1) {
        return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i', '$1****$2', $phone);
    } else {
        return preg_replace('/(1[358]{1}[0-9])[0-9]{4}([0-9]{4})/i', '$1****$2', $phone);
    }
}

/**
 * 生成签名
 * @param $data 待签名数据
 * @param $appsecret 应用Appsecret
 * @return string
 */
function getSign($data, $appsecret)
{
    $signPars = "";
    ksort($data);
    foreach ($data as $k => $v) {
        if ("sign" != $k && "" != $v && $v != "0") {
            $signPars .= $k . "=" . $v . "&";
        }
    }
    $signPars .= "key=" . $appsecret;
    return strtoupper(md5($signPars));
}

/**
 * @Title: getNextMonthDays
 * @Describe 获取下个月时间
 * @param $date
 * @return array|false|string
 * @author lijunwei
 * @Date 2021/10/22 17:06
 */
function getNextMonthDays($date)
{
    $timestamp = strtotime($date);
    $arr = getdate($timestamp);
    if ($arr['mon'] == 12) {
        $year = $arr['year'] + 1;
        $month = $arr['mon'] - 11;
        $firstday = $year . '0' . $month;
    } else {
        $firstday = date('Ym', strtotime(date('Y', $timestamp) . '-' . (date('m', $timestamp) + 1)));
    }
    return $firstday;
}

if (!function_exists('send_email_by_submail')) {
    /**
     * Notes: 使用塞有云发送邮件
     * User: allen
     * DateTime: 2021/8/17 上午11:27
     * @param $to
     * @param $subject
     * @param $content
     * @return mixed
     */
    function send_email_by_submail($to, $subject, $content)
    {
        $config = config('app.email');
        $param = [
            'appid' => $config['appid'],
            'signature' => $config['signature'],
            'from' => $config['from'],
            'to' => $to,
            'subject' => $subject,
            'html' => $content,
        ];
        $res = curlRequest($config['mail_url'], true, $param);
        $send_res = json_decode($res, true);
        if (!$send_res || strtolower($send_res['status']) != 'success') {
            //失败
            errorLog('send_email_by_submail', $send_res);
            return false;
        }
        return true;
    }
}

if (!function_exists('code_check')) {

    /**
     * 验证码校验
     * @param $account
     * @param $code
     * @param $suffix
     * @param int $is_del
     * @param bool $is_mobile
     * @return mixed
     */
    function code_check($account, $code, $suffix, $is_del = 1, $is_mobile = true)
    {
        $redis = redis(1);
        $key = $is_mobile ? sprintf(CacheKey::MOBILE_CODE, $account . '_' . $suffix) : sprintf(CacheKey::EMAIL_CODE, $account . '_' . $suffix);
        $real_code = $redis->get($key);

        // 如果验证码不存在，则已过期
        if (!$real_code) {
            return returnJson(Status::VERIFY_PAST_CODE, lang('msg_code_past'), []);
        }

        // 用户传的验证码和真实验证码不一致则验证码错误
        if ($code != $real_code && explode('.', $real_code)[0] != $code) {
            //防止恶意刷验证码接口
            if (strpos($real_code, '.') !== false) {
                $real_code_arr = explode('.', $real_code);
                $value = $real_code_arr[0] . '.' . ($real_code_arr['1'] + 1);
                if ($real_code_arr['1'] >= 4) {
                    //连续错5次，可能是恶意盗刷接口,从0开始的
                    $redis->del($key);
                    return returnJson(Status::VERIFY_PAST_CODE, lang('msg_code_time_error'));
                }
            } else {
                //说明是第一次错误
                $value = $real_code . '.1';
            }
            //redis缓存时间
            $redis->set($key, $value, 60);
            return returnJson(Status::VERIFY_ERROR_CODE, lang('msg_code_error'));
        }

        // 验证正确，删除已使用的验证码
        if ($is_del) {
            $redis->del($key);
        }
        return true;
    }
}

//function socketApi()
//{
//    error_reporting(E_ALL);
//    set_time_limit(0);
//
//    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
//    if ($socket === false) {
//        $error_code = socket_last_error();
//        $error_msg = socket_strerror($error_code);
//        die("Couldn't create socket: [$error_code] $error_msg");
//    }
//
//    $result = socket_connect($socket, $this->ip, $this->port);
//    if (!$result) {
//        $this->errorStr = "socket_connect() failed.\nReason: ($result) " . socket_strerror($result) . "\n";
//        return $this->errorStr;
//    }
//
//    $in = $this->bodyTit . $this->bodyXml;
//    if (!socket_write($socket, $in, strlen($in))) {
//        $this->errorStr = "socket_write() failed: reason: " . socket_strerror($socket) . "\n";
//        return $this->errorStr;
//    }
//
//    while ($out = @socket_read($socket, 8192)) {
//        $this->outTradingType = substr($out, 87, 6);
//        $this->outSubject = trim(substr($out, 93, 100));
//        $this->outBodyTit = substr($out, 0, 222);
//        if ($this->outTradingType == '000000') {
//            $this->outBodyXml = substr($out, 222);
////            $this->outXmlArr = self::xmlToArray($this->outBodyXml);
//
//        } else {
//            $this->errCode = $this->outTradingType;
//            $this->errStr = $this->outSubject;
//            return $this->errStr;
//        }
//    }
//
//    socket_close($socket);
//    return $this->errStr;
//}

/**
 * User: kyle
 * Date: 2021/7/22
 * Time: 2:30 下午
 * description 直接返回响应
 * @param $msg
 * @param $msg_code
 * @param int $code
 */
function ResponseDirect($msg = "", $msg_code = 400, $code = 200)
{
    $msg = $msg ?: lang('system_error');
    throw new think\exception\HttpResponseException(json([
        'code' => $msg_code,
        'data' => '',
        'msg' => $msg
    ], $code));
}

/**
 * Notes: 获取各种手续费
 * User: allen
 * DateTime: 2021/11/3 下午5:30
 * @param string $name
 * @return mixed
 */
function getSystemConfig($name)
{
    if (!$name) {
        return false;
    }
    $config = \app\admin\model\SysConfig::getInstance()->getValues(['name' => $name]);
    if (is_null($config)) {
        //没有配置，返回失败
        errorLog('getSystemConfig', '配置表缺少配置名:' . $name);
        ResponseDirect(lang('system_error'), Status::FAILED);
    }
    return $config;
}

/**
 * 获取当前竞猜价格
 * @param $type
 * @param $time
 * @param int $retry
 * @return ExchangeMarket|int
 */
function getNowPrice($type, $time, $retry = 0)
{
    $redis = redis();
    $key = CacheKey::SELECT_PRICE;
    $num = $redis->get($key);
    // 价格异常
    if ($num >= 10) {
        $redis->del($key);
        return 0;
    }
    // 当前时间
    $price = ExchangeMarket::getInstance(date("Ym"))->getOne(['genotype' => $type, 'ec_time' => date('Y-m-d H:i:s', $time)], 'purchase_price', 'id desc');
    if (empty($price) && in_array($retry, [0, 2])) {
        $reduce_key = CacheKey::PRICE_REDUCE_TIME;
        $now_time = $redis->get($reduce_key) ?: $time;
        $reduce_time = $now_time - 1;
        $redis->incr($key);
        $redis->set($reduce_key, $reduce_time, 5);
        $price = getNowPrice($type, $reduce_time, 1);
    }
    if (empty($price) && $retry == 1) {
        $add_key = CacheKey::PRICE_ADD_TIME;
        $now_time = $redis->get($add_key) ?: $time;
        if ($num == 1) {
            $add_time = $now_time + 2;
        } else {
            $add_time = $now_time + 1;
        }
        $redis->incr($key);
        $redis->set($add_key, $add_time, 5);
        $price = getNowPrice($type, $add_time, 2);
    }
    $redis->del($key);
    return $price['purchase_price'] ?? $price;
}

function getDecByType($type)
{
    switch ($type) {
        case 1:
            $dec = 'GC';
            break;
        case 2:
            $dec = 'SI';
            break;
        case 3:
            $dec = 'CL';
            break;
        case 4:
            $dec = 'HG';
            break;
        default:
            $dec = 'GC';
    }
    return $dec;
}

/**
 * @Title: getInrRate
 * @Description: 获取INR兑美元的汇率
 * @param $source  原币
 * @param $target  兑换币
 * @param $time  缓存时间
 * @return bool
 * @Author: 李军伟
 */
function getInrRate($source = 'USD', $target = 'INR', $time = 43200)
{
    $redis = redis();
    $source = strtoupper($source);
    $target = strtoupper($target);
    $key = "{$source}_TO_{$target}_RATE";
    $res_rate = $redis->get($key);
    if ($res_rate) {
        return $res_rate;
    }
    //过期了，重新请求
    $rate = requestInrRate($source, $target);
    $redis->set($key, $rate, $time);
    return $rate;
}

/**
 * @param $source
 * @param $target 市场兑换比例
 * @return bool
 */
function requestInrRate($source, $target)
{
    $a_parm['app'] = 'finance.rate';
    $a_parm['scur'] = $source;
    $a_parm['tcur'] = $target;
    $a_parm['appkey'] = config('NOWAPI_APP_KEY');
    $a_parm['sign'] = config('NOWAPI_SIGN');
    $a_parm['format'] = 'json';

    //combinations
    $a_parm['format'] = empty($a_parm['format']) ? 'json' : $a_parm['format'];
    $apiurl = empty($a_parm['apiurl']) ? 'http://api.k780.com/?' : $a_parm['apiurl'] . '/?';
    unset($a_parm['apiurl']);
    foreach ($a_parm as $k => $v) {
        $apiurl .= $k . '=' . $v . '&';
    }
    $apiurl = substr($apiurl, 0, -1);
    if (!$callapi = file_get_contents($apiurl)) {
        return false;
    }
    //format
    if ($a_parm['format'] == 'base64') {
        $a_cdata = unserialize(base64_decode($callapi));
    } elseif ($a_parm['format'] == 'json') {
        if (!$a_cdata = json_decode($callapi, true)) {
            return false;
        }
    } else {
        return false;
    }
    //array
    if ($a_cdata['success'] != '1') {
        echo $a_cdata['msgid'] . ' ' . $a_cdata['msg'];
        return false;
    }
    return $a_cdata['result']['rate'];
}

/**
 * Notes: 保留小数
 * User: allen
 * DateTime: 2021/11/4 下午5:53
 * @param $num
 * @param int $float
 * @return string|null
 */
function hold($num, $float = 2)
{
    if (is_numeric($num)) {
        return bcdiv($num, 1, $float);
    }
    return $num;
}

/**
 * Notes: 获取团队人数
 * User: allen
 * DateTime: 2021/11/8 下午4:14
 * @param $uid
 * @return int
 */
function getTeamNum($uid)
{
    $sql = "SELECT COUNT(id) as num FROM uf_member WHERE FIND_IN_SET({$uid},directly_ids)";
    $res = Db::query($sql);
    return $res[0]['num'] ?? 0;
}

/**
 * Notes: 获取直推人数
 * User: allen
 * DateTime: 2021/11/8 下午4:38
 * @param $uid
 * @return Member
 */
function getDirectPushNum($uid)
{
    return Member::getInstance()->getCount(['pid' => $uid], 'id');
}

/**
 * @Title: uniqueArr
 * @Describe 二维数组根据某个字段去重
 * @param $array
 * @param $word
 * @return array
 * @author lijunwei
 * @Date 2021/11/10 10:31
 */
function uniqueArr($array, $word)
{
    $result = array();
    foreach ($array as $val) {
        $code = false;
        foreach ($result as &$_val) {
            if ($_val[$word] == $val[$word]) {
                $code = true;
                break;
            }
        }
        if (!$code) {
            $result[] = $val;
        }
    }
    return $result;
}

/**
 * @Title: inGold
 * @Describe 返回inGold金额
 * @param $gold
 * @return float|int
 * @author lijunwei
 * @Date 2022/1/4 13:44
 */
function inGold($gold)
{
    return hexdec($gold) / 1000000000000000000;
}

/**
 * @Title: getConfig
 * @Describe 获取指定的配置信息
 * @param $name
 * @return mixed
 * @author lijunwei
 * @Date 2022/1/4 17:01
 */
function getConfig($name)
{
    return SysConfig::getInstance()->getValues(['name' => $name]);
}

/**
 * @param array $list 数据
 * @param array $header 表头
 * @param string $name 表名称
 * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
 */
function outExcel($list, $header, $name)
{
    $newExcel = new Spreadsheet();              // 创建一个新的excel文档
    $objSheet = $newExcel->getActiveSheet();    // 获取当前操作sheet的对象
    $objSheet->setTitle($name);                // 设置当前sheet的标题

    // 设置表头
    foreach ($header as $k => $v) {
        $coordinate = $k . 1;
        $objSheet->setCellValue($coordinate, $v['title']);
    }
    // 设置表体
    foreach ($list as $k => $v) {
        $i = $k + 2;
        foreach ($header as $key => $val) {
            $coordinate = $key . $i;
            $objSheet->setCellValue($coordinate, $v[$val['value']]);
        }
    }
    /*--------------下面是设置其他信息------------------*/
    header('Content-Type: application/vnd.ms-excel');
    header("Content-Disposition: attachment;filename={$name}.xls");
    header('Cache-Control: max-age=0');
    $objWriter = IOFactory::createWriter($newExcel, 'Xls');
    $objWriter->save('php://output');
    exit();
}